home *** CD-ROM | disk | FTP | other *** search
/ FM Towns: Free Software Collection 4 / FM Towns Free Software Collection 4 - Disc 1.iso / t_os / tie / src / wc.c < prev    next >
C/C++ Source or Header  |  1991-10-18  |  34KB  |  1,232 lines

  1. #include    <stdio.h>
  2. #include    <stdlib.h>
  3. #include    <string.h>
  4. #include    <ctype.h>
  5. #include    <msdos.cf>
  6. #include    <egb.h>
  7. #include    <mos.h>
  8. #include    <fmc.h>
  9. #include    <snd.h>
  10. #include    "tie.h"
  11. #include    "cons.h"
  12.  
  13. #define TRUE    1
  14. #define FALSE   0
  15. #define ERR     (-1)
  16.  
  17. #define OFS_Y           32      /*  全体をタイトルのぶん下げてある  */
  18.  
  19. #define CARD_X          468
  20. #define CARD_Y          20+OFS_Y
  21. #define CARD_LEN        12
  22.  
  23. #define DRV_X           68
  24. #define DRV_Y           20+OFS_Y
  25. #define DRV_MAX         17      /* A - Q */
  26. #define DRV_LEN         8
  27.  
  28. #define CLIP_SIZ        30
  29. #define CLIP_LEN        2
  30. #define CLIP_X          156
  31. #define CLIP_DOWN       (CLIP_X+CLIP_SIZ*8+8)
  32. #define CLIP_UP         (CLIP_DOWN+CLIP_LEN*8+6)
  33. #define CLIP_Y          (3+OFS_Y)
  34.  
  35. #define DSP_X           156
  36. #define DSP_LEN         36
  37.  
  38. #define FNT_SIZ         16      /*  16ドットに固定  */
  39.  
  40. #define FNT_SPC_X       2
  41. #define FNT_SPC_Y       1
  42.  
  43. #define DSP_Y           (26+OFS_Y)
  44. #define DSP_MAX         19      /*  一度に表示するファイルの数  */
  45.  
  46. #define SPC_Y           19      /*  一行の縦方向のドット数(全体)  */
  47. #define SIZ_Y           17      /*  一行の縦方向のドット数(文字部分)  */
  48.  
  49. #define WIND_COL        5
  50. #define STD_COL         14
  51. #define BACK_COL        5
  52. #define HIT_COL         6
  53. #define BOX1_COL        7
  54. #define BOX2_COL        8
  55. #define XOR1_COL        14
  56. #define XOR2_COL        3
  57.  
  58. #define ISDIR(c)        (c->att&0x10)
  59.  
  60. #define IS_FLP          0x00
  61. #define IS_CDR          0x01
  62. #define IS_SCSI         0x02
  63. #define IS_RAM          0x03
  64. #define IS_MDC          0x04
  65. #define IS_ROM          0x05
  66. #define IS_NON          0xFF
  67.  
  68. #define DISKSTAT_UNKNOWN 0      /*  知らん  */
  69. #define DISKSTAT_READY   1      /*  準備よし  */
  70. #define DISKSTAT_NOTREADY 2     /*  準備できてない  */
  71.  
  72. typedef struct _WCBUF
  73. {
  74.     struct _WCBUF   *next ;
  75.     short int       mark ;
  76.     short int       att ;
  77.     u_short         time, date ;
  78.     u_long          size ;
  79.     char            name[14] ;
  80. } WCBUF ;
  81.  
  82. typedef struct _DISK
  83. {
  84.     int     disktype ;  /*  ディスク種別  */
  85.     int     drivenum ;  /*  ドライブ番号  */
  86.     int     ready ;     /*  READY ?  */
  87. } DISK ;
  88.  
  89. static  int     drv_max = ERR ;     /*  現在有効なドライブ数  */
  90.  
  91. static  DISK    disk[ DRV_MAX ] =
  92. {
  93.     IS_NON,0,0, IS_NON,0,0, IS_NON,0,0, IS_NON,0,0, IS_NON,0,0, IS_NON,0,0,
  94.     IS_NON,0,0, IS_NON,0,0, IS_NON,0,0, IS_NON,0,0, IS_NON,0,0, IS_NON,0,0,
  95.     IS_NON,0,0, IS_NON,0,0, IS_NON,0,0, IS_NON,0,0, IS_NON,0,0,
  96. } ;
  97. static  char    *dev_name[] =
  98. {
  99.     "FD  ", "CD",   "HD  ", "RAM ", "MDC ", "ROM ", "????"
  100. } ;
  101.  
  102. static  CDBUF   card[ CARD_MAX ] ;
  103.  
  104. static  int     CDRV = -1, event = ERR ;
  105. static  int     click_pos = 0 ;     /*  パスリストのどこをクリックしたのか  */
  106. static  int     stat_sw ;           /*  マウスのスイッチ  */
  107. static  char    crrdir[256] ;       /*  現在のカレント・ディレクトリ  */
  108. static  int     curpos = 12 ;       /*  編集行のカーソル位置  */
  109. static  int     mark_file = -1 ;    /*  マークされているファイル  */
  110. static  WCBUF   *mark_wp = NULL ;   /*  マークファイルのWCBUF  */
  111.  
  112. extern  void    down_key_chk( int sw ) ;
  113. extern  void    up_key_chk( int sw ) ;
  114. extern  int     wc_del( int ) ;
  115. extern  void    init_drv_table( void ) ;
  116.  
  117.  
  118.  
  119. /*  READY かどうか調べる  */
  120.  
  121. static  int     check_drive( int i )
  122. {
  123.     auto    u_int   stat, ret ;
  124.     auto    int     devnum, j ;
  125.     auto    DISK    *dp ;
  126.  
  127.     dp = &disk[ i ] ;
  128.  
  129.     switch( dp->disktype )
  130.     {
  131.         case IS_FLP:  devnum = 0x20 | dp->drivenum ; break ;
  132.         case IS_SCSI: devnum = 0xB0 | dp->drivenum ; break ;
  133.         case IS_CDR:  devnum = 0xC0 | dp->drivenum ; break ;
  134.         case IS_RAM:
  135.         case IS_ROM: return( DISKSTAT_READY ) ;
  136.         default:
  137.             return( dp->ready = DISKSTAT_UNKNOWN ) ;
  138.     }
  139.  
  140.     j = ( dp->disktype == IS_CDR ) ? 3 : 1 ;
  141.     while( j-- > 0 && ( ret = DKB_rdstatus( devnum, &stat ) ) == 0x8080 ) ;
  142.  
  143.     switch( ret )
  144.     {
  145.       case 0x0000: return( dp->ready = DISKSTAT_READY ) ;
  146.       case 0x8001: return( dp->ready = DISKSTAT_NOTREADY ) ;
  147.       default:     return( dp->ready = DISKSTAT_UNKNOWN ) ;
  148.     }
  149. }
  150.  
  151. /*  カレントドライブを変更する  */
  152.  
  153. void    chdrv( int no )
  154. {
  155.     CDRV = no ;
  156.  
  157.     init_drv_table() ;
  158.  
  159.     if( check_drive( no ) != DISKSTAT_READY )
  160.         return ;
  161.  
  162.     Registers.AX.R = 0x0E00 ;
  163.     Registers.DX.R = no ;
  164.     calldos() ;
  165. }
  166.  
  167. /*  カレントディレクトリを変更する  */
  168.  
  169. void    chdir( char *name )
  170. {
  171.     init_drv_table() ;
  172.  
  173.     Registers.AX.R = 0x3B00 ;
  174.     Registers.DX.R = (int)name ;
  175.     Registers.DS.R = getds() ;
  176.     calldos() ;
  177. }
  178.  
  179. /*  カレントドライブを通知する  */
  180.  
  181. int     getdrv( void )
  182. {
  183.     Registers.AX.R = 0x1900 ;     /* Get Current Disk Drive */
  184.     calldos() ;
  185.  
  186.     return Registers.AX.LH.L & 0xFF ;
  187. }
  188.  
  189. /*  カレントディレクトリを通知する  */
  190.  
  191. int     getdir( char *name )
  192. {
  193.     int     drv ;
  194.  
  195.     init_drv_table() ;
  196.  
  197.     if( check_drive( CDRV ) != DISKSTAT_READY )
  198.     {
  199.         sprintf( name, "%c:", 'A'+CDRV ) ;
  200.         return CDRV ;
  201.     }
  202.  
  203.     Registers.AX.R = 0x4700 ;
  204.     Registers.DX.R = 0x0000 ;
  205.     Registers.SI.R = (int)name+3 ;
  206.     Registers.DS.R = getds() ;
  207.     calldos() ;
  208.  
  209.     *(name++) = 'A' + ( drv = CDRV ) ;
  210.     *(name++) = ':' ;
  211.     *(name++) = '\\' ;
  212.     if( *name != '\0' )
  213.         strcat( name, "\\" ) ;
  214.  
  215.     return drv ;
  216. }
  217.  
  218. static  WCBUF   *wc_read( char *arg, int mode )
  219. {
  220.     static int   opflg = FALSE ;
  221.     static struct
  222.     {
  223.         u_char  dd_dmy[22] ;
  224.         u_short dd_time, dd_date ;
  225.         u_long  dd_size ;
  226.         char    dd_name[13] ;
  227.     } dta ;
  228.     auto    WCBUF   *wp ;
  229.  
  230.     if( disk[ CDRV ].ready == DISKSTAT_NOTREADY )
  231.         return( NULL ) ;
  232.  
  233.     if( opflg == FALSE )
  234.     {
  235.         Registers.AX.R = 0x1A00 ;       /*  ファイル検索時のバッファ指定  */
  236.         Registers.DX.R = (int)&dta ;    /*  ファイル検索時のバッファ  */
  237.         Registers.DS.R = getds() ;
  238.         calldos() ;
  239.  
  240.         Registers.AX.R = 0x4E00 ;       /*  初回のファイル検索  */
  241.         Registers.CX.R = mode ;         /*  検索するファイルの属性  */
  242.         Registers.DX.R = (int)arg ;
  243.         Registers.DS.R = getds() ;
  244.         opflg = TRUE ;
  245.     }
  246.     else
  247.         Registers.AX.R = 0x4F00 ;       /*  2回目以降のファイル検索  */
  248.     calldos() ;
  249.  
  250.     if( ( Registers.Flags & 0x0001 ) != 0 ) /*  エラーチェック  */
  251.     {
  252.         opflg = FALSE ;
  253.         return NULL ;
  254.     }
  255.  
  256.     if( ( wp = (WCBUF *)malloc( sizeof( WCBUF ) ) ) != NULL )
  257.     {
  258.         wp->next = NULL ;
  259.         wp->mark = FALSE ;
  260.         wp->att = dta.dd_dmy[21] ;
  261.         wp->date = dta.dd_date ;
  262.         wp->time = dta.dd_time ;
  263.         wp->size = dta.dd_size ;
  264.         strcpy( wp->name, dta.dd_name ) ;
  265.     }
  266.  
  267.     return wp ;
  268. }
  269.  
  270. static  char    toup( char ch )
  271. {
  272.     return toupper(ch) ;
  273. }
  274.  
  275. static  int     patmatch( char *arg, char *nam )
  276. {
  277.     int     i,j;
  278.  
  279.     for( ; *arg != '\0' && *nam != '\0' ; )
  280.     {
  281.         i = toup(*(arg++)) ;
  282.         j = toup(*(nam++)) ;
  283.         if( i == '*' )
  284.         {
  285.             do {
  286.                 if( (i = toup(*(arg++))) == '\0' )
  287.                     return TRUE ;
  288.             } while ( i == '*' || i == '?' ) ;
  289.             do {
  290.                 if ( j == i && patmatch(arg,nam) == TRUE )
  291.                     return TRUE;
  292.             } while ( (j = toup(*(nam++))) != '\0' );
  293.             if ( i == '.' && *arg == '*' )
  294.                 return TRUE;
  295.             else
  296.                 return FALSE;
  297.         }
  298.         else if ( i != '?' && i != j )
  299.             return FALSE;
  300.     }
  301.     if ( *arg == '\0' && *nam == '\0' )
  302.         return TRUE;
  303.     else
  304.         return FALSE;
  305. }
  306.  
  307. /*  拡張子があれば、その先頭のポインタなければ¥0を返す  */
  308. static  char    *subname( register char *name )
  309. {
  310.     static  char    *nul = "\0" ;
  311.     auto    char    *p ;
  312.  
  313.     if( *name == '.' || ( p = strrchr( name, '.' ) ) == NULL )
  314.         name = nul ;
  315.     else
  316.         name = p + 1 ;
  317.  
  318.     return name ;
  319. }
  320.  
  321. static  char    *formname( char *name )
  322. {
  323.     char    *p;
  324.     static  char    tmp[ 14 ] ;
  325.     auto    char    tmp2[ 16 ] ;
  326.  
  327.     strcpy( tmp2, name ) ;
  328.     if( *( p = subname( tmp2 ) ) != '\0' )  /*  拡張子あり  */
  329.         *(p-1) = '\0' ;
  330.     sprintf( tmp, "%-8s %-3s", tmp2, p ) ;
  331.  
  332.     return tmp ;
  333. }
  334.  
  335. static  int     cmpname( REGS WCBUF *sp, REGS WCBUF *dp )
  336. {
  337.     REGS    int     cd ;
  338.  
  339.     if( ISDIR(sp) != ISDIR(dp) )
  340.         return ISDIR(sp) ? ERR : TRUE ;
  341.     if( ( cd = strcmp( subname(sp->name), subname(dp->name) ) ) != 0 )
  342.         return cd ;
  343.     return strcmp( sp->name, dp->name ) ;
  344. }
  345.  
  346. static  void    wc_reset( WCBUF *wp )
  347. {
  348.     WCBUF   *tp ;
  349.  
  350.     while( wp != NULL )
  351.     {
  352.         tp = wp->next ;
  353.         free( wp ) ;
  354.         wp = tp ;
  355.     }
  356. }
  357.  
  358. static  int     wild_chk( char *file )
  359. {
  360.     int     i;
  361.  
  362.     for( i = 0 ; i < CARD_MAX ; i++ ) {
  363.         if( card[i].mark != FALSE && patmatch( card[i].name, file ) )
  364.             return TRUE ;
  365.     }
  366.     return FALSE;
  367. }
  368.  
  369. static  WCBUF   *wc_sort( WCBUF *sp, WCBUF *dp )
  370. {
  371.     REGS    WCBUF   *tp ;
  372.     auto    WCBUF   tmp ;
  373.  
  374.     tp = &tmp ;
  375.     if( ( tp->next = sp ) == NULL )
  376.         return dp ;
  377. /* #define TEST */
  378. #ifdef  TEST
  379.     if( tp->next != NULL )
  380.         tp = tp->next ;
  381. #else
  382.     while( tp->next != NULL )
  383.     {
  384.         if( cmpname( tp->next, dp ) >= 0 )
  385.             break ;
  386.         tp = tp->next ;
  387.     }
  388. #endif
  389.     dp->next = tp->next ;
  390.     tp->next = dp ;
  391.  
  392.     return tmp.next ;
  393. }
  394.  
  395. static  WCBUF   *wc_open()
  396. {
  397.     WCBUF   *topwp = NULL ;
  398.     WCBUF   *wp ;
  399.  
  400.     if( getdrv() != CDRV )  /*  カレントドライブが違う!  */
  401.         return NULL ;
  402.  
  403.     mos_ptn( 2 ) ;
  404.     while( ( wp = wc_read( "*.*", 0x31 ) ) != NULL )
  405.     {
  406.         if( wp->name[0] == '.' && wp->name[1] == '\0' )
  407.             free( wp ) ;
  408.         else if( ISDIR( wp ) || wild_chk( wp->name ) )
  409.         {
  410. #ifdef TEST
  411.             wp->next = topwp ;
  412.             topwp = wp ;
  413. #else
  414.             topwp = wc_sort( topwp, wp ) ;
  415. #endif
  416.         }
  417.         else
  418.             free( wp ) ;
  419.     }
  420.  
  421.  
  422.     mos_ptn( 0 ) ;
  423.  
  424.     return topwp ;
  425. }
  426.  
  427. static  void    DSP_file_chk( REGS EVENT *ep, int x, int y, int sw )
  428. {
  429.     y = y ;         /*  意味なし  ワーニング回避  */
  430.  
  431.     switch( ep->now )
  432.     {
  433.       case EVT_ON_MOS:      /*  ボタンの上にいるときは、カーソルを変更  */
  434.         mos_ptn( 1 ) ;
  435.         break ;
  436.       case EVT_OFF_MOS:
  437.         mos_ptn( 0 ) ;
  438.         break ;
  439.  
  440.       case EVT_CLIP_MOS:    /*  押した時はへこむ  */
  441.         mos_ptn( 1 ) ;
  442.         stat_sw = sw ;
  443.         DSP_clip_on( ep ) ;
  444.         break ;
  445.  
  446.       case EVT_DOLACK_MOS:  /*  押したまま、外れると戻る  */
  447.         ep->now = EVT_NON ;
  448.       case EVT_MOVE_MOS:
  449.         DSP_clip_off( ep ) ;
  450.         mos_ptn( 0 ) ;
  451.         break ;
  452.  
  453.       case EVT_SELECT_MOS:  /*  その場で離すと、実行  */
  454.         event = ep->no ;
  455.         click_pos = ( x - ep->x1 ) / 8 ;
  456.         DSP_clip_off( ep ) ;
  457.         mos_ptn( 0 ) ;
  458.         break ;
  459.     }
  460. }
  461.  
  462. static  void    ITEM_clip( REGS EVENT *ep, int x, int y, int sw )
  463. {
  464.     sw = sw, y = y ;        /*  意味なし  ワーニング回避  */
  465.  
  466.     switch( ep->now )
  467.     {
  468.       case EVT_ON_MOS:      /*  ボタンの上にいるときは、カーソルを変更  */
  469.       case EVT_CLIP_MOS:
  470.         mos_ptn( 6 ) ;
  471.         break ;
  472.  
  473.       case EVT_DOLACK_MOS:  /*  外れたら戻す  */
  474.         ep->now = EVT_NON ;
  475.       case EVT_MOVE_MOS:
  476.       case EVT_OFF_MOS:
  477.         mos_ptn( 0 ) ;
  478.         break ;
  479.  
  480.       case EVT_SELECT_MOS:  /*  その場で離すと、その位置を覚える  */
  481.         event = ep->no ;
  482.         curpos = ( x - ep->x1 ) / 8 ;
  483.         mos_ptn( 1 ) ;
  484.         break ;
  485.     }
  486. }
  487.  
  488.  
  489. static  void    down_key_chk( int sw )
  490. {
  491.     wrt("▼", writepage, CLIP_DOWN+FNT_SPC_X, CLIP_Y+FNT_SPC_Y,
  492.            col_tbl[sw == FALSE ? 7:STD_COL],
  493.            col_tbl[BACK_COL], FNT_SIZ ) ;
  494. }
  495. static  void    up_key_chk( int sw )
  496. {
  497.     wrt( "▲", writepage, CLIP_UP+FNT_SPC_X, CLIP_Y+FNT_SPC_Y,
  498.            col_tbl[sw == FALSE ? 7:STD_COL],
  499.            col_tbl[BACK_COL], FNT_SIZ ) ;
  500. }
  501.  
  502.  
  503. /*  ファイル名の表示  */
  504.  
  505. static  void    dsp_name( REGS WCBUF *wp, int top, int num )
  506. {
  507.     static  char    dmy[256] ;
  508.  
  509.     sprintf( dmy, "%-12s ", formname( wp->name ) ) ;
  510.  
  511.     if( ISDIR( wp ) )
  512.         sprintf( dmy + 13, "   <DIR> " ) ;
  513.     else
  514.         sprintf( dmy + 13, "%8ld ", wp->size ) ;
  515.  
  516.     sprintf( dmy + 22,"%02d-%02d-%02d %02d:%02d",
  517.         80+(wp->date >> 9),
  518.         (wp->date >> 5) & 0x0F,
  519.         wp->date & 0x1F,
  520.         wp->time >> 11,
  521.         (wp->time >> 5) & 0x3F ) ;
  522.  
  523.     wrt( dmy, writepage, DSP_X+FNT_SPC_X, DSP_Y+FNT_SPC_Y+SPC_Y*num,
  524.          col_tbl[STD_COL],
  525. /*       col_tbl[ ( wp!=NULL && wp->mark != FALSE ) ? HIT_COL:BACK_COL ], */
  526.          col_tbl[ ( wp!=NULL && num == mark_file-top ) ? HIT_COL:BACK_COL ],
  527.          FNT_SIZ ) ;
  528. }
  529.  
  530. /*  ファイル一覧パネルの表示  */
  531.  
  532. static  void    dsp_all( REGS WCBUF *wp, int top, int re_write )
  533. {
  534.     int     i ;
  535.     char    tmp[256], tmp2[256] ;
  536.     char    *p ;
  537.  
  538.     EVT_level_free( 101 ) ;
  539.  
  540.     MOS_disp( MOS_OFF ) ;
  541.  
  542.     strcpy( tmp, crrdir ) ;
  543.     if( ( p = strrchr( tmp, '\\' ) ) != NULL && strlen( tmp ) > 3 )
  544.         *p = '\0' ;     /*  余計な \ をつぶす  */
  545.     sprintf( tmp2, "%-29s", tmp ) ;
  546.     tmp2[29] = '\0' ;
  547.     wrt( tmp2, writepage, CLIP_X+FNT_SPC_X, CLIP_Y+FNT_SPC_Y,
  548.            col_tbl[STD_COL], col_tbl[BACK_COL], FNT_SIZ ) ;
  549.  
  550.     if( re_write )
  551.     {
  552.         dsp_box( DSP_X-2,DSP_Y-2,
  553.                  DSP_X+DSP_LEN*8+4+2,DSP_Y+(DSP_MAX-1)*SPC_Y+SIZ_Y+2,
  554.                  BOX1_COL,BOX2_COL,WIND_COL);
  555.     }
  556.  
  557.     for( i = 0 ; wp != NULL && i < DSP_MAX ; i++ )
  558.     {
  559.         dsp_box( DSP_X,DSP_Y+i*SPC_Y,
  560.                  DSP_X+DSP_LEN*8+4,DSP_Y+i*SPC_Y+SIZ_Y,
  561.                  BOX1_COL,BOX2_COL,
  562.                  wp->mark != FALSE ? HIT_COL:BACK_COL ) ;
  563.         EVT_set_node(DSP_X,DSP_Y+i*SPC_Y,
  564.                      DSP_X+DSP_LEN*8+4,DSP_Y+i*SPC_Y+SIZ_Y,
  565.                      101,DSP_file_chk,i,FALSE ) ;
  566.         dsp_name( wp, top, i ) ;
  567.         wp = wp->next ;
  568.     }
  569.  
  570.     for( ; i < DSP_MAX ; i++ )
  571.         dsp_box( DSP_X, DSP_Y+i*SPC_Y,
  572.                  DSP_X+DSP_LEN*8+4, DSP_Y+i*SPC_Y+SIZ_Y,
  573.                  BACK_COL, BACK_COL, BACK_COL ) ;
  574.  
  575.     down_key_chk( wp != NULL ? TRUE:FALSE ) ;
  576.     up_key_chk( top > 0 ? TRUE:FALSE ) ;
  577.  
  578.     MOS_disp( MOS_ON ) ;
  579. }
  580.  
  581.  
  582. /*  ワイルドカード・パネルの表示  */
  583.  
  584. static  void    dsp_card( int flush )
  585. {
  586.     auto    int     i;
  587.     static  CDBUF   cardbuf[ CARD_MAX ] ;
  588.  
  589.     EVT_level_free( 102 ) ;
  590.  
  591.     MOS_disp( MOS_OFF ) ;
  592.  
  593.     if( flush )
  594.         dsp_box( CARD_X-2,CARD_Y-2,
  595.                  CARD_X+CARD_LEN*8+4+2,CARD_Y+(CARD_MAX-1)*SPC_Y+SIZ_Y+2,
  596.                  BOX1_COL,BOX2_COL,WIND_COL ) ;
  597.  
  598.     for( i = 0 ; i < CARD_MAX ; i ++ )
  599.     {
  600.         if( card[i].name != NULL )
  601.             EVT_set_node( CARD_X,CARD_Y+i*SPC_Y,
  602.                           CARD_X+CARD_LEN*8+4,CARD_Y+i*SPC_Y+SIZ_Y,
  603.                           102,DSP_file_chk,i+DSP_MAX,FALSE);
  604.  
  605.         if( flush || cardbuf[i].name != card[i].name ||
  606.                      cardbuf[i].mark != card[i].mark )
  607.         {
  608.             cardbuf[i].name = card[i].name ;
  609.             cardbuf[i].mark = card[i].mark ;
  610.  
  611.             if( card[i].name != NULL )
  612.             {
  613.                 dsp_box( CARD_X,CARD_Y+i*SPC_Y,
  614.                          CARD_X+CARD_LEN*8+4,CARD_Y+i*SPC_Y+SIZ_Y,
  615.                          BOX1_COL,BOX2_COL,
  616.                          card[i].name != NULL && 
  617.                          card[i].mark != FALSE ? HIT_COL:BACK_COL);
  618.  
  619.                 wrt( formname(card[i].name),
  620.                     writepage, CARD_X+FNT_SPC_X, CARD_Y+FNT_SPC_Y+SPC_Y*i,
  621.                     COL_1,
  622.                     col_tbl[card[i].mark != FALSE ? HIT_COL:BACK_COL],
  623.                     FNT_SIZ ) ;
  624.             }
  625.             else
  626.                 dsp_box( CARD_X,CARD_Y+i*SPC_Y,
  627.                          CARD_X+CARD_LEN*8+4,CARD_Y+i*SPC_Y+SIZ_Y,
  628.                          BACK_COL, BACK_COL, BACK_COL ) ;
  629.         }
  630.     }
  631.     MOS_disp( TRUE ) ;
  632. }
  633.  
  634. static  void    init_drv_table( void )
  635. {
  636.     int     i ;
  637.     u_char  info[200] ;
  638.  
  639.     if( drv_max != ERR )    /*  既に初期化済  */
  640.         return ;
  641.  
  642.     ESR_setupInfo( (char *)info ) ;  /*  システム情報取得  */
  643.  
  644.     for( drv_max = i = 0 ; i < DRV_MAX ; i ++ )
  645.     {
  646.         switch( disk[i].disktype = info[0x30 + i * 2] )
  647.         {
  648.           case IS_FLP:      /*  FLOPPY DISK  */
  649.             disk[i].drivenum = info[0x31 + i * 2] ; break ;
  650.  
  651.           case IS_CDR:      /*  CD-ROM DRIVE  */
  652.             disk[i].drivenum = 0 ; break ;
  653.  
  654.           case IS_SCSI:     /*  SCSI HARD DISK  */
  655.             disk[i].drivenum = info[0x31 + i * 2] >> 4 ; break ;
  656.  
  657.           case IS_RAM:      /*  RAM DISK  */
  658.             disk[i].drivenum = 0 ; break ;
  659.  
  660.           case IS_ROM:      /*  ROM DISK  */    /*  意味なし  */
  661.             /*disk[i].drivenum = 0 ; break ;*/
  662.           case IS_MDC:      /*  MDC HARD DISK  : 処理法が不明のため  */
  663.           default:          /*  IS_NON(未割り当て) か 不明  */
  664.             disk[i].disktype = IS_NON ;     /*  処理法が不明のため  */
  665.             continue ;
  666.         }
  667.         drv_max ++ ;
  668.     }
  669.  
  670. /*    getdir( (char *)info ) ;
  671.     CDRV = info[0] - 'A' ; */
  672.     CDRV = getdrv() ;
  673. }
  674.  
  675.  
  676. /*  ドライブ名パネルの表示  */
  677.  
  678. static  void    dsp_drive( int re_write )
  679. {
  680.     static  int     last_cdrv = -1 ;
  681.     int     i, n, dt ;
  682.  
  683.  
  684.     init_drv_table() ;
  685.  
  686.     EVT_level_free( 303 ) ;
  687.  
  688.     MOS_disp( FALSE ) ;
  689.  
  690.     if( re_write )
  691.     {
  692.         last_cdrv = -1 ;
  693.  
  694.         dsp_box( DRV_X-2, DRV_Y-2,
  695.                  DRV_X+DRV_LEN*8+4+2, DRV_Y+(drv_max-1)*(SPC_Y+4)+4+SIZ_Y+2,
  696.                  BOX1_COL, BOX2_COL, WIND_COL ) ;
  697.     }
  698.  
  699.     for( i = n = 0 ; i < DRV_MAX ; i ++ )
  700.     {
  701.         if( ( dt = disk[i].disktype ) != IS_NON )
  702.         {
  703.             if( re_write || i == last_cdrv || i == CDRV )
  704.             {
  705.                 dsp_box( DRV_X, DRV_Y+n*(SPC_Y+4),
  706.                          DRV_X+DRV_LEN*8+4, DRV_Y+n*(SPC_Y+4)+3+SIZ_Y,
  707.                          BOX1_COL, BOX2_COL,
  708.                          i == CDRV ? HIT_COL:BACK_COL ) ;
  709. #define DEVICE_ICON
  710. #ifdef DEVICE_ICON
  711.                 if( dt == 0 && i < 3 )      /*  内蔵FDは特別扱い  */
  712.                     dt = 6 ;
  713.                 DSP_ptn( DRV_X+FNT_SPC_X+7, DRV_Y+FNT_SPC_Y+(SPC_Y+4)*n+3,
  714.                                                     14,12, drv_icn[i], 1 ) ;
  715.                 DSP_ptn( DRV_X+FNT_SPC_X+25, DRV_Y+FNT_SPC_Y+(SPC_Y+4)*n+2,
  716.                                                     31,14, dev_icn[dt], 1 ) ;
  717. #else
  718.     char    tmp[ 16 ] ;
  719.                 sprintf( tmp, " %c: %s", i + 'A',
  720.                                     dev_name[ disk[i].disktype ] ) ;
  721.                 wrt( tmp, writepage, DRV_X+FNT_SPC_X, DRV_Y+FNT_SPC_Y+SPC_Y*n,
  722.                      col_tbl[STD_COL],
  723.                      col_tbl[i == CDRV ? HIT_COL:BACK_COL], FNT_SIZ ) ;
  724. #endif
  725.             }
  726.  
  727.             EVT_set_node( DRV_X, DRV_Y+n*(SPC_Y+4),
  728.                           DRV_X+DRV_LEN*8+4, DRV_Y+n*(SPC_Y+4)+3+SIZ_Y,
  729.                           103, DSP_file_chk, i+DSP_MAX+CARD_MAX,FALSE ) ;
  730.             n ++ ;
  731.         }
  732.     }
  733.  
  734.     MOS_disp( TRUE ) ;
  735.  
  736.     last_cdrv = CDRV ;
  737. }
  738.  
  739.  
  740. /*  最上段の一行を表示  */
  741.  
  742. static  void    dsp_clip( void )
  743. {
  744.     EVT_level_free( 104 ) ;
  745.  
  746.     MOS_disp( OFF ) ;
  747.  
  748.     dsp_box( CLIP_X-2,CLIP_Y-2, CLIP_UP+CLIP_LEN*8+4+3,CLIP_Y+SIZ_Y+2,
  749.                     BOX1_COL,BOX2_COL,WIND_COL ) ;
  750.  
  751.     EVT_set_node( CLIP_X,CLIP_Y, CLIP_X+CLIP_SIZ*8+4,CLIP_Y+SIZ_Y,
  752.                     104,DSP_file_chk,503, OFF ) ;
  753.     dsp_box( CLIP_X,CLIP_Y, CLIP_X+CLIP_SIZ*8+4,CLIP_Y+SIZ_Y,
  754.                     BOX1_COL,BOX2_COL,BACK_COL ) ;
  755.     wrt( "  <<< FILE SELECTER >>> ", writepage,
  756.                     CLIP_X+FNT_SPC_X, CLIP_Y+FNT_SPC_Y,
  757.                     col_tbl[STD_COL], col_tbl[BACK_COL], FNT_SIZ ) ;
  758.  
  759.     dsp_box( CLIP_DOWN,CLIP_Y, CLIP_DOWN+CLIP_LEN*8+4,CLIP_Y+SIZ_Y,
  760.                     BOX1_COL,BOX2_COL,BACK_COL ) ;
  761.     down_key_chk( FALSE ) ;
  762.     EVT_set_node( CLIP_DOWN,CLIP_Y, CLIP_DOWN+CLIP_LEN*8+4,CLIP_Y+SIZ_Y,
  763.                     104,DSP_file_chk,501, OFF ) ;
  764.  
  765.     dsp_box( CLIP_UP,CLIP_Y, CLIP_UP+CLIP_LEN*8+4,CLIP_Y+SIZ_Y,
  766.                     BOX1_COL,BOX2_COL,BACK_COL ) ;
  767.     up_key_chk( FALSE ) ;
  768.     EVT_set_node( CLIP_UP,CLIP_Y, CLIP_UP+CLIP_LEN*8+4,CLIP_Y+SIZ_Y,
  769.                     104,DSP_file_chk,502, OFF ) ;
  770.  
  771.     MOS_disp( ON ) ;
  772. }
  773.  
  774. static  void    dsp_ttl( char *msg )
  775. {
  776.     int     len, xs ;
  777.  
  778.     if( ( len = strlen( msg ) ) > 70 || len < 4 )  /*  表示しない  */
  779.         return ;
  780.  
  781.     xs = 320 - len*8/2 - 32 - 18 ;
  782.     dsp_box( xs,8, xs+len*8+64,28, 7,8,5 ) ;
  783.     wrt( msg, writepage, xs+32,10, COL_14,COL_5, 16 ) ;
  784. }
  785.  
  786. static  void    clr_scrn()
  787. {
  788.     MOS_disp( FALSE ) ;
  789.     EGB_color( egbwork,1,0 ) ;
  790.     EGB_clearScreen( egbwork ) ;
  791.     MOS_disp( TRUE ) ;
  792. }
  793.  
  794. static  void    click_cancel()
  795. {
  796.     event = 500 ;   /*  キャンセル  */
  797. }
  798.  
  799.  
  800. /*  ファイル名入力ダイアログの表示  */
  801.  
  802. static  int     FNAM_X, FNAM_Y ;
  803.  
  804. static  void    dsp_filename( int keyin )
  805. {
  806.     int     x,y, xs,ys ;
  807.  
  808.     x = FNAM_X = DSP_X ;
  809.     y = FNAM_Y = DSP_Y+(DSP_MAX-1)*SPC_Y+SIZ_Y+6 ;
  810.  
  811.     MOS_disp( MOS_OFF ) ;
  812.  
  813.     dsp_box( x-2,y-2, ( xs = x+DSP_LEN*8+4+2 ),y+SIZ_Y+2+2,
  814.              BOX1_COL,BOX2_COL,WIND_COL ) ;
  815.  
  816.     if( keyin )                 /*  テキスト入力行  */
  817.     {
  818.         dsp_box( x+1,y, x+8*12+3,y+SIZ_Y+2, 1,1,15 ) ;
  819.         EVT_set_node( x+1,y, x+8*12+3,y+SIZ_Y+2, 104,ITEM_clip,600, OFF ) ;
  820.     }
  821.  
  822.     x = xs - 98 ;
  823.  
  824.     xs = 5*8 + FNT_SPC_X * 2 + 2 ;
  825.     ys = SIZ_Y + FNT_SPC_Y * 2 ;
  826.  
  827.     dsp_box( x,y, x+xs,y+ys, BOX1_COL,BOX2_COL,BACK_COL ) ;
  828.     EVT_set_node( x,y, x+xs,y+ys, 104,DSP_file_chk,504, OFF ) ;
  829.     wrt( "決 定", writepage, x+FNT_SPC_X+2,y+FNT_SPC_Y+1,
  830.                 col_tbl[STD_COL],col_tbl[BACK_COL], FNT_SIZ ) ;
  831.  
  832.     x += 48 ;
  833.     dsp_box( x,y, x+xs,y+ys, BOX1_COL,BOX2_COL,BACK_COL ) ;
  834.     EVT_set_node( x,y, x+xs,y+ys, 104,DSP_file_chk,500, OFF ) ;
  835.     wrt( "中 止", writepage, x+FNT_SPC_X+2,y+FNT_SPC_Y+1,
  836.                     col_tbl[STD_COL],col_tbl[BACK_COL], FNT_SIZ ) ;
  837.  
  838.     MOS_disp( MOS_ON ) ;
  839. }
  840.  
  841.  
  842. /*  ファイルを選択する  */
  843.  
  844. char    *file_select( char *def_file, char *msg, CDBUF wc[], int dirflag )
  845. {
  846.     auto    int     i, top ;
  847.     auto    int     keyin ;
  848.     auto    WCBUF   *topwp ;
  849.     auto    WCBUF   *twp, *wp ;
  850.     auto    char    *file = NULL ;
  851.     auto    char    *p ;
  852.     auto    int     ch, win_close = TRUE ;
  853.     auto    char    filenamebuf[16] ;
  854.     auto    int     now_mouse, now_mark, db ;
  855.     static  int     last_mouse = 0 ;
  856.     static  int     last_mark = 0 ;
  857.  
  858.  
  859.     if( def_file == NULL )
  860.         keyin = FALSE ;
  861.     else
  862.     {
  863.         keyin = TRUE ;
  864.  
  865.         strcpy( crrdir, def_file ) ;
  866.         if( ( p = strrchr( crrdir, '\\' ) ) != NULL && p[1] != '\0' )
  867.         {
  868.             strcpy( filenamebuf, p+1 ) ;
  869.             *p = '\0' ;
  870.             if( strlen( crrdir ) < 3 )
  871.                 crrdir[2] = '\\', crrdir[3] = '\0' ;
  872.             chdrv( toupper( crrdir[0] ) - 'A' ) ;
  873.             chdir( crrdir ) ;
  874.         }
  875.         else
  876.             filenamebuf[0] = '\0' ;     /*  こんなことはないハズ・・・  */
  877.     }
  878.  
  879.     memcpy( card, wc, sizeof( card ) ) ;
  880.  
  881.     getdir( crrdir ) ;
  882.  
  883.     MOS_disp( FALSE ) ;
  884.  
  885.     MOS_writePage( 1 ) ;
  886.     MOS_horizon ( MIN_HORIZON,  MAX_HORIZON ) ;
  887.     MOS_vertical( MIN_VERTICAL, MAX_VERTICAL ) ;
  888.  
  889.     DSP_writePage( egbwork, 1 ) ;
  890.  
  891.     EVT_control_cancel( FALSE ) ;   /*  右クリック・キャンセルの使用停止  */
  892.     EVT_set_ground( 110, click_cancel ) ;
  893.     EVT_control_ground( TRUE ) ;    /*  余白クリックでキャンセル  */
  894.     clr_scrn() ;
  895.     dsp_clip() ;
  896.     dsp_drive( TRUE ) ;
  897.     dsp_card( TRUE ) ;
  898.     dsp_ttl( msg ) ;
  899.     dsp_filename( keyin ) ;
  900.  
  901.     topwp = twp = wc_open() ;
  902.     mark_file = -1 ;
  903.     dsp_all( twp, 0, TRUE ) ;
  904.     top = 0 ;
  905.  
  906.     KAN_dispMode() ;        /*  モード再表示  */
  907.     MOS_disp( MOS_ON ) ;
  908.  
  909.     keyflush() ;
  910.  
  911.     for( ; ; )
  912.     {
  913.         if( keyin && win_close )
  914.         {
  915.             wind_open( FNAM_X+3,FNAM_Y+2,12, &curpos, 1,15,5, filenamebuf ) ;
  916.             win_close = FALSE ;
  917.         }
  918.  
  919.         event = ERR ;
  920.         while( 1 )
  921.         {
  922.             EVT_loop( 100,200 ) ;
  923.  
  924.             if( event != ERR || kbhit( OFF ) != FALSE )
  925.                 break ;
  926.         }
  927.  
  928.         if( kbhit( OFF ) != FALSE )       /*  キー入力センス  */
  929.         {
  930.             if( ( ch = getch() ) == 0x1B )  /*  エスケープで中止  */
  931.                 event = 500 ;
  932.             else if( ch == 0x8073 )         /*  実行キーで実行  */
  933.                 event = 504 ;
  934.             else
  935.             {
  936.                 event = ERR ;
  937.                 if( keyin && ch != 0x0D )   /*  リターンキーは無視  */
  938.                     putch( ch ) ;
  939.             }
  940.         }
  941.  
  942.         if( event == ERR )
  943.             continue ;
  944.  
  945.         if( event == 600 )          /*  カーソル移動  */
  946.             win_close = TRUE ;
  947.         if( event == 500 )          /*  キャンセル  */
  948.             break ;
  949.         else if( event == 501 )     /*  下矢印  */
  950.         {
  951.             for( i = DSP_MAX ,wp = twp ; i > 0 && wp != NULL ; i-- )
  952.                 wp = wp->next ;
  953.             if( wp != NULL )
  954.             {
  955.                 top += DSP_MAX ;
  956.                 twp = wp ;
  957.                 dsp_all( twp, top, FALSE ) ;
  958.             }
  959.         }
  960.         else if( event == 502 )     /*  上矢印  */
  961.         {
  962.             if( top > 0 )
  963.             {
  964.                 top -= DSP_MAX ;
  965.                 for( i = 0 ,wp = topwp ; i < top && wp != NULL ; i++ )
  966.                     wp = wp->next ;
  967.                 twp = wp ;
  968.                 dsp_all( twp, top, FALSE ) ;
  969.             }
  970.         }
  971.         else if( event == 503 )     /*  上方へ移動  */
  972.         {
  973.             if( click_pos < strlen( crrdir ) )
  974.             {
  975.                 if( click_pos < 3 )     /*  ルート  */
  976.                     *( crrdir + 3 ) = '\0' ;
  977.                 else
  978.                 {
  979.                     for( p = crrdir + click_pos ; *p && *p != '\\' ; p ++ ) ;
  980.                     *p = '\0' ;
  981.                 }
  982.                 chdir( crrdir ) ;
  983.                 getdir( crrdir ) ;
  984.                 wc_reset( topwp ) ;
  985.                 topwp = twp = wc_open() ;
  986.                 mark_file = -1 ;
  987.                 dsp_all( twp, 0, FALSE ) ;
  988.                 top = 0 ;
  989.             }
  990.         }
  991.         else if( event == 504 )     /*  決定  */
  992.         {
  993.             if( keyin )
  994.                 wind_close(), win_close = TRUE ;
  995.  
  996.             if( mark_file == -1 )       /*  無視  */
  997.                 if( !( keyin && strlen( filenamebuf ) > 0 ) )
  998.                     continue ;
  999.  
  1000.             if( keyin )
  1001.                 strcat( crrdir, filenamebuf ) ; /*  フルパスにして渡す  */
  1002.             else
  1003.             {
  1004.                 if( ISDIR( mark_wp ) && dirflag == OFF )
  1005.                     continue ;
  1006.  
  1007.                 strcat( crrdir, mark_wp->name ) ;   /*  フルパスにして渡す  */
  1008.  
  1009.                 if( ISDIR( mark_wp ) )
  1010.                     strcat( crrdir, "\x10" ) ;  /*  末尾に0x10を付加  */
  1011.             }
  1012.  
  1013.             file = crrdir ;
  1014.             break ;
  1015.         }
  1016.         else if( event < DSP_MAX )  /*  ファイルを選択  */
  1017.         {
  1018.             for( i = 0, wp = twp ; i < event && wp != NULL ; i++ )
  1019.                 wp = wp->next ;
  1020.  
  1021.             if( rbtn( stat_sw ) == TRUE )   /*  右クリックによる選択  */
  1022.             {
  1023.                 char    tmp[ 128 ] ;
  1024.  
  1025.                 if( *( p = subname( wp->name ) ) != '\0' )
  1026.                 {                                   /*  拡張子があれば  */
  1027.                     sprintf( tmp, "*.%s", p ) ;
  1028.                     event = wc_apend( tmp, TRUE ) ;
  1029.                     goto RE_PRINT ;
  1030.                 }
  1031.                 continue ;
  1032.             }
  1033.  
  1034.             /*  ダブル・クリックの確認  */
  1035.             now_mouse = MOS_getTime() ;
  1036.             now_mark = event + top ;
  1037.             if( now_mark == last_mark && now_mouse <= last_mouse + 15 )
  1038.                 db = TRUE ;
  1039.             else
  1040.                 db = FALSE ;
  1041.             last_mouse = now_mouse ;
  1042.             last_mark = now_mark ;
  1043.  
  1044.             if( ISDIR( wp ) && db )     /*  指定のディレクトリへ移動  */
  1045.             {
  1046.                 chdir( wp->name ) ;
  1047.                 getdir( crrdir ) ;
  1048.                 wc_reset( topwp ) ;
  1049.                 topwp = twp = wc_open() ;
  1050.                 mark_file = -1 ;
  1051.                 dsp_all( twp, 0, FALSE ) ;
  1052.                 top = 0 ;
  1053.             }
  1054.             else                        /*  マークのセットと解除  */
  1055.             {
  1056.                 if( mark_file == now_mark )
  1057.                 {
  1058.                     mark_file = -1 ;
  1059.                     MOS_disp( MOS_OFF ) ;
  1060.                     dsp_name( wp, top, event ) ;
  1061.                     MOS_disp( MOS_ON ) ;
  1062.                 }
  1063.                 else
  1064.                 {
  1065.                     MOS_disp( MOS_OFF ) ;
  1066.  
  1067.                     if( mark_file >= top && mark_file <= top + DSP_MAX )
  1068.                     {
  1069.                         int tmp = mark_file - top ;
  1070.                         mark_file = -1 ;
  1071.                         dsp_name( mark_wp, top, tmp ) ;
  1072.                     }
  1073.  
  1074.                     mark_file = now_mark ;
  1075.                     mark_wp = wp ;
  1076.                     dsp_name( wp, top, event ) ;
  1077.  
  1078.                     MOS_disp( MOS_ON ) ;
  1079.                 }
  1080.  
  1081.                 if( keyin )         /*  キー入力可能  */
  1082.                 {
  1083.                     wind_close() ;
  1084.                     win_close = TRUE ;
  1085.                     dsp_box( FNAM_X+1,FNAM_Y,
  1086.                              FNAM_X+8*12+3,FNAM_Y+SIZ_Y+2, 1,1,15 ) ;
  1087.                     strcpy( filenamebuf, wp->name ) ;
  1088.                 }
  1089.             }
  1090.         }
  1091.         else if( ( event -= DSP_MAX ) < CARD_MAX )  /*  ワイルド・カード  */
  1092.         {
  1093.             if( rbtn( stat_sw ) == TRUE )   /*  右クリックによる選択  */
  1094.             {
  1095.                 if( wc_del( event ) != ERR )
  1096.                     goto RE_PRINT ;
  1097.                 continue ;
  1098.             }
  1099.  
  1100.             if( card[event].name != NULL )
  1101.             {
  1102.                 card[event].mark = card[event].mark != FALSE ? FALSE:TRUE ;
  1103.  
  1104. RE_PRINT:
  1105.                 dsp_card( FALSE ) ;
  1106.  
  1107.                 /*  "*.*" が押されてない時だけ  */
  1108.                 if( event == 0 || card[0].mark == FALSE )
  1109.                 {
  1110.                     wc_reset( topwp ) ;
  1111.                     topwp = twp = wc_open() ;
  1112.                     mark_file = -1 ;
  1113.                     dsp_all( topwp, 0, FALSE ) ;
  1114.                     top = 0 ;
  1115.                 }
  1116.             }
  1117.         }
  1118.         else if( ( event -= CARD_MAX ) < DRV_MAX )  /*  ドライブ・セレクト  */
  1119.         {
  1120.             CDRV = event ;
  1121.             dsp_drive( FALSE ) ;
  1122.             mos_ptn( 2 ) ;
  1123.             chdrv( event ) ;
  1124.             getdir( crrdir ) ;
  1125.             wc_reset( topwp ) ;
  1126.             topwp = twp = wc_open() ;
  1127.             mark_file = -1 ;
  1128.             dsp_all( twp, 0, FALSE ) ;
  1129.             top = 0 ;
  1130.         }
  1131.     }
  1132.  
  1133.     EVT_level_free( 101 ) ;
  1134.     EVT_level_free( 102 ) ;
  1135.     EVT_level_free( 103 ) ;
  1136.     EVT_level_free( 104 ) ;
  1137.     EVT_level_free( 105 ) ;
  1138.     EVT_level_free( 110 ) ;
  1139.  
  1140.     wind_close() ;
  1141.     wc_reset( topwp ) ;
  1142.     clr_scrn() ;
  1143.  
  1144.     EVT_control_ground( FALSE ) ;
  1145.     EVT_control_cancel( TRUE ) ;    /*  右クリック・キャンセルの使用再開  */
  1146.  
  1147.     memcpy( wc, card, sizeof( card ) ) ;
  1148.  
  1149.     return file ;
  1150. }
  1151.  
  1152.  
  1153. /*  削除する。失敗したらERRを返す  */
  1154.  
  1155. static  int     wc_del( int no )
  1156. {
  1157.     int     i, j ;
  1158.     int     find ;
  1159.  
  1160.     if( !card[no].allocate || card[no].name == NULL )
  1161.         return ERR ;
  1162.     free( card[no].name ) ;
  1163.  
  1164.     for( i = no ; i < CARD_MAX ; i ++ )
  1165.     {
  1166.         find = FALSE ;
  1167.  
  1168.         for( j = i + 1 ; j < CARD_MAX ; j ++ )
  1169.             if( card[j].name != NULL )
  1170.             {
  1171.                 card[i].name = card[j].name ;
  1172.                 card[i].mark = card[j].mark ;
  1173.                 card[i].allocate = card[j].allocate ;
  1174.  
  1175.                 card[j].name = NULL ;
  1176.                 card[j].mark = FALSE ;
  1177.                 card[i].allocate = TRUE ;
  1178.  
  1179.                 find = TRUE ;
  1180.                 break ;
  1181.             }
  1182.  
  1183.         if( !find )
  1184.         {
  1185.             card[i].name = NULL ;
  1186.             card[i].mark = FALSE ;
  1187.             card[i].allocate = TRUE ;
  1188.             break ;
  1189.         }
  1190.     }
  1191.  
  1192.     return( ERR+1 ) ;
  1193. }
  1194.  
  1195.  
  1196. /*  ワイルドーカードを追加する。
  1197.     登録成功か、すでに登録されていた場合はスロット番号を返す。
  1198.     失敗なら ERR を返す  */
  1199.  
  1200. int     wc_apend( char *name, int mode )
  1201. {
  1202.     int     i ;
  1203.     char    *p ;
  1204.  
  1205.     if( ( p = strrchr( name, '\\' ) ) != NULL )
  1206.         name = p + 1 ;
  1207.  
  1208.     for( p = name = strdup( name ) ; *p != '\0' ; p ++ )
  1209.         *p = toup( *p ) ;
  1210.  
  1211.     for( i = 0 ; i < CARD_MAX ; i++ )
  1212.         if( card[i].name != NULL && strcmp( card[i].name, name ) == 0 )
  1213.         {
  1214.             if( mode == TRUE )
  1215.                 card[i].mark = card[i].mark != FALSE ? FALSE:TRUE ;
  1216.             return( i ) ;
  1217.         }
  1218.  
  1219.     for( i = 0 ; i < CARD_MAX ; i++ )
  1220.     {
  1221.         if( card[i].name == NULL )
  1222.         {
  1223.             card[i].name = name ;
  1224.             card[i].mark = mode ;
  1225.             return( i ) ;
  1226.         }
  1227.     }
  1228.  
  1229.     return( ERR ) ;
  1230. }
  1231.  
  1232.